home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / gnulib / dkbtrace / pbmplus / source / ppm / ppmtopic.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-06  |  11.1 KB  |  484 lines

  1. /*
  2. ** ppmtopict.c - read a portable pixmap and produce a Macintosh PICT2 file.
  3. **
  4. ** Copyright (C) 1990 by Ken Yap <ken@cs.rochester.edu>.
  5. **
  6. ** Permission to use, copy, modify, and distribute this software and its
  7. ** documentation for any purpose and without fee is hereby granted, provided
  8. ** that the above copyright notice appear in all copies and that both that
  9. ** copyright notice and this permission notice appear in supporting
  10. ** documentation.  This software is provided "as is" without express or
  11. ** implied warranty.
  12. */
  13.  
  14. #include "ppm.h"
  15. #include "ppmcmap.h"
  16.  
  17. #define HEADER_SIZE        512
  18.  
  19. #define    RUN_THRESH        3
  20. #define    MAX_RUN            128        /* 0xff = 2, 0xfe = 3, etc */
  21. #define    MAX_COUNT        128        /* 0x00 = 1, 0x01 = 2, etc */
  22.  
  23. /* Opcodes */
  24. #define PICT_NOP        0x00
  25. #define PICT_clipRgn        0x01
  26. #define PICT_bkPat        0x02
  27. #define PICT_txFont        0x03
  28. #define PICT_txFace        0x04
  29. #define PICT_txMode        0x05
  30. #define PICT_spExtra        0x06
  31. #define PICT_pnSize        0x07
  32. #define PICT_pnMode        0x08
  33. #define PICT_pnPat        0x09
  34. #define PICT_thePat        0x0A
  35. #define PICT_ovSize        0x0B
  36. #define PICT_origin        0x0C
  37. #define PICT_txSize        0x0D
  38. #define PICT_fgColor        0x0E
  39. #define PICT_bkColor        0x0F
  40. #define PICT_txRatio        0x10
  41. #define PICT_picVersion        0x11
  42. #define    PICT_blPixPat        0x12
  43. #define    PICT_pnPixPat        0x13
  44. #define    PICT_fillPixPat        0x14
  45. #define    PICT_pnLocHFrac        0x15
  46. #define    PICT_chExtra        0x16
  47. #define    PICT_rgbFgCol        0x1A
  48. #define    PICT_rgbBkCol        0x1B
  49. #define    PICT_hiliteMode        0x1C
  50. #define    PICT_hiliteColor    0x1D
  51. #define    PICT_defHilite        0x1E
  52. #define    PICT_opColor        0x1F
  53. #define PICT_line        0x20
  54. #define PICT_line_from        0x21
  55. #define PICT_short_line        0x22
  56. #define PICT_short_line_from    0x23
  57. #define PICT_long_text        0x28
  58. #define PICT_DH_text        0x29
  59. #define PICT_DV_text        0x2A
  60. #define PICT_DHDV_text        0x2B
  61. #define PICT_frameRect        0x30
  62. #define PICT_paintRect        0x31
  63. #define PICT_eraseRect        0x32
  64. #define PICT_invertRect        0x33
  65. #define PICT_fillRect        0x34
  66. #define PICT_frameSameRect    0x38
  67. #define PICT_paintSameRect    0x39
  68. #define PICT_eraseSameRect    0x3A
  69. #define PICT_invertSameRect    0x3B
  70. #define PICT_fillSameRect    0x3C
  71. #define PICT_frameRRect        0x40
  72. #define PICT_paintRRect        0x41
  73. #define PICT_eraseRRect        0x42
  74. #define PICT_invertRRect    0x43
  75. #define PICT_fillRRect        0x44
  76. #define PICT_frameSameRRect    0x48
  77. #define PICT_paintSameRRect    0x49
  78. #define PICT_eraseSameRRect    0x4A
  79. #define PICT_invertSameRRect    0x4B
  80. #define PICT_fillSameRRect    0x4C
  81. #define PICT_frameOval        0x50
  82. #define PICT_paintOval        0x51
  83. #define PICT_eraseOval        0x52
  84. #define PICT_invertOval        0x53
  85. #define PICT_fillOval        0x54
  86. #define PICT_frameSameOval    0x58
  87. #define PICT_paintSameOval    0x59
  88. #define PICT_eraseSameOval    0x5A
  89. #define PICT_invertSameOval    0x5B
  90. #define PICT_fillSameOval    0x5C
  91. #define PICT_frameArc        0x60
  92. #define PICT_paintArc        0x61
  93. #define PICT_eraseArc        0x62
  94. #define PICT_invertArc        0x63
  95. #define PICT_fillArc        0x64
  96. #define PICT_frameSameArc    0x68
  97. #define PICT_paintSameArc    0x69
  98. #define PICT_eraseSameArc    0x6A
  99. #define PICT_invertSameArc    0x6B
  100. #define PICT_fillSameArc    0x6C
  101. #define PICT_framePoly        0x70
  102. #define PICT_paintPoly        0x71
  103. #define PICT_erasePoly        0x72
  104. #define PICT_invertPoly        0x73
  105. #define PICT_fillPoly        0x74
  106. #define PICT_frameSamePoly    0x78
  107. #define PICT_paintSamePoly    0x79
  108. #define PICT_eraseSamePoly    0x7A
  109. #define PICT_invertSamePoly    0x7B
  110. #define PICT_fillSamePoly    0x7C
  111. #define PICT_frameRgn        0x80
  112. #define PICT_paintRgn        0x81
  113. #define PICT_eraseRgn        0x82
  114. #define PICT_invertRgn        0x83
  115. #define PICT_fillRgn        0x84
  116. #define PICT_frameSameRgn    0x88
  117. #define PICT_paintSameRgn    0x89
  118. #define PICT_eraseSameRgn    0x8A
  119. #define PICT_invertSameRgn    0x8B
  120. #define PICT_fillSameRgn    0x8C
  121. #define PICT_BitsRect        0x90
  122. #define PICT_BitsRgn        0x91
  123. #define PICT_PackBitsRect    0x98
  124. #define PICT_PackBitsRgn    0x99
  125. #define PICT_shortComment    0xA0
  126. #define PICT_longComment    0xA1
  127. #define PICT_EndOfPicture    0xFF
  128. #define    PICT_headerOp        0x0C00
  129.  
  130. static void putFill ARGS(( FILE *fd, int n ));
  131. static void putShort ARGS(( FILE *fd, int i ));
  132. static void putLong ARGS(( FILE *fd, long i ));
  133. static void putFixed ARGS(( FILE *fd, int in, int frac ));
  134. static void putRect ARGS(( FILE *fd, int x1, int x2, int y1, int y2 ));
  135. static int putRow ARGS(( FILE *fd, int row, int cols, pixel *rowpixels, char *packed ));
  136.  
  137. #define MAXCOLORS 256
  138. static colorhash_table cht;
  139.  
  140. void
  141. main(argc, argv)
  142. int argc;
  143. char *argv[];
  144. {
  145.     FILE *ifp;
  146.     int argn, rows, cols, colors, i, row, oc;
  147.     register pixel **pixels;
  148.     char *packed;
  149.     pixval maxval;
  150.     long lmaxval, rval, gval, bval;
  151.     colorhist_vector chv;
  152.  
  153.     ppm_init( &argc, argv );
  154.  
  155.     argn = 1;
  156.     if (argn < argc)
  157.     {
  158.         ifp = pm_openr(argv[1]);
  159.         argn++;
  160.     }
  161.     else
  162.         ifp = stdin;
  163.     if (argn != argc)
  164.         pm_usage("[ppmfile]");
  165.  
  166.     pixels = ppm_readppm(ifp, &cols, &rows, &maxval);
  167.     if (cols < 8)
  168.         pm_error("ppm input too narrow, must be >= 8 pixels wide" );
  169.     lmaxval = (long)maxval;
  170.     pm_close(ifp);
  171.  
  172.     /* Figure out the colormap. */
  173.     pm_message("computing colormap..." );
  174.     chv = ppm_computecolorhist(pixels, cols, rows, MAXCOLORS, &colors);
  175.     if (chv == (colorhist_vector) 0)
  176.         pm_error("too many colors - try doing a 'ppmquant %d'", MAXCOLORS);
  177.     pm_message("%d colors found", colors );
  178.  
  179.     /* Make a hash table for fast color lookup. */
  180.     cht = ppm_colorhisttocolorhash(chv, colors);
  181.  
  182.     /* write the header */
  183.     putFill(stdout, HEADER_SIZE);
  184.  
  185.     /* write picSize and picFrame */
  186.     putShort(stdout, 0);
  187.     putRect(stdout, 0, 0, rows, cols);
  188.  
  189.     /* write version op and version */
  190.     putShort(stdout, PICT_picVersion);
  191.     putShort(stdout, 0x02FF);
  192.     putShort(stdout, PICT_headerOp);
  193.     putLong(stdout, -1L);
  194.     putFixed(stdout, 0, 0);
  195.     putFixed(stdout, 0, 0);
  196.     putFixed(stdout, cols, 0);
  197.     putFixed(stdout, rows, 0);
  198.     putFill(stdout, 4);
  199.  
  200.     /* seems to be needed by many PICT2 programs */
  201.     putShort(stdout, PICT_clipRgn);
  202.     putShort(stdout, 10);
  203.     putRect(stdout, 0, 0, rows, cols);
  204.  
  205.     /* write picture */
  206.     putShort(stdout, PICT_PackBitsRect);
  207.     putShort(stdout, cols | 0x8000);
  208.     putRect(stdout, 0, 0, rows, cols);
  209.     putShort(stdout, 0);    /* pmVersion */
  210.     putShort(stdout, 0);    /* packType */
  211.     putLong(stdout, 0L);    /* packSize */
  212.     putFixed(stdout, 72, 0);    /* hRes */
  213.     putFixed(stdout, 72, 0);    /* vRes */
  214.     putShort(stdout, 0);    /* pixelType */
  215.     putShort(stdout, 8);    /* pixelSize */
  216.     putShort(stdout, 1);    /* cmpCount */
  217.     putShort(stdout, 8);    /* cmpSize */
  218.     putLong(stdout, 0L);    /* planeBytes */
  219.     putLong(stdout, 0L);    /* pmTable */
  220.     putLong(stdout, 0L);    /* pmReserved */
  221.     putLong(stdout, 0L);    /* ctSeed */
  222.     putShort(stdout, 0);    /* ctFlags */
  223.     putShort(stdout, colors-1);    /* ctSize */
  224.  
  225.     /* Write out the colormap. */
  226.     for (i = 0; i < colors; i++)
  227.     {
  228.         putShort(stdout, i);
  229.         rval = PPM_GETR(chv[i].color);
  230.         gval = PPM_GETG(chv[i].color);
  231.         bval = PPM_GETB(chv[i].color);
  232.         if (lmaxval != 65535L)
  233.         {
  234.             rval = rval * 65535L / lmaxval;
  235.             gval = gval * 65535L / lmaxval;
  236.             bval = bval * 65535L / lmaxval;
  237.         }
  238.         putShort(stdout, (short)rval);
  239.         putShort(stdout, (short)gval);
  240.         putShort(stdout, (short)bval);
  241.     }
  242.  
  243.     putRect(stdout, 0, 0, rows, cols);    /* srcRect */
  244.     putRect(stdout, 0, 0, rows, cols);    /* dstRect */
  245.     putShort(stdout, 0);            /* mode */
  246.  
  247.     /* Finally, write out the data. */
  248.     packed = (char*) malloc((unsigned)(cols+cols/MAX_COUNT+1));
  249.     oc = 0;
  250.     for (row = 0; row < rows; row++)
  251.         oc += putRow(stdout, row, cols, pixels[row], packed);
  252.  
  253.     /* if we wrote an odd number of pixdata bytes, pad */
  254.     if (oc & 1)
  255.         (void) putc(0, stdout);
  256.     putShort(stdout, PICT_EndOfPicture);
  257.  
  258.     lmaxval = ftell(stdout) - HEADER_SIZE;
  259.     if (fseek(stdout, (long)HEADER_SIZE, 0) >= 0)
  260.         putShort(stdout, (short)(lmaxval & 0xffff));
  261.  
  262.     pm_close (stdout);
  263.  
  264.     exit(0);
  265. }
  266.  
  267. static void
  268. putFill(fd, n)
  269. FILE *fd;
  270. int n;
  271. {
  272.     register int i;
  273.  
  274.     for (i = 0; i < n; i++)
  275.         (void) putc(0, fd);
  276. }
  277.  
  278. static void
  279. putShort(fd, i)
  280. FILE *fd;
  281. int i;
  282. {
  283.     (void) putc((i >> 8) & 0xff, fd);
  284.     (void) putc(i & 0xff, fd);
  285. }
  286.  
  287. #if __STDC__
  288. static void
  289. putLong( FILE *fd, long i )
  290. #else /*__STDC__*/
  291. static void
  292. putLong(fd, i)
  293. FILE *fd;
  294. long i;
  295. #endif /*__STDC__*/
  296. {
  297.     (void) putc((int)((i >> 24) & 0xff), fd);
  298.     (void) putc(((int)(i >> 16) & 0xff), fd);
  299.     (void) putc(((int)(i >> 8) & 0xff), fd);
  300.     (void) putc((int)(i & 0xff), fd);
  301. }
  302.  
  303. static void
  304. putFixed(fd, in, frac)
  305. FILE *fd;
  306. int in, frac;
  307. {
  308.     putShort(fd, in);
  309.     putShort(fd, frac);
  310. }
  311.  
  312. static void
  313. putRect(fd, x1, x2, y1, y2)
  314. FILE *fd;
  315. int x1, x2, y1, y2;
  316. {
  317.     putShort(fd, x1);
  318.     putShort(fd, x2);
  319.     putShort(fd, y1);
  320.     putShort(fd, y2);
  321. }
  322.  
  323. #define    RUNLENGTH
  324. #ifdef    RUNLENGTH
  325.  
  326. #define        runtochar(c)    (257-(c))
  327. #define        counttochar(c)    ((c)-1)
  328.  
  329. static int
  330. putRow(fd, row, cols, rowpixels, packed)
  331. FILE *fd;
  332. int row, cols;
  333. pixel *rowpixels;
  334. char *packed;
  335. {
  336.     register int i;
  337.     int packcols, count, run, rep, oc;
  338.     register pixel *pP;
  339.     pixel lastp;
  340.     register char *p;
  341.  
  342.     run = count = 0;
  343.     for (cols--, i = cols, pP = rowpixels + cols, p = packed, lastp = *pP;
  344.         i >= 0; i--, lastp = *pP, pP--)
  345.     {
  346.         if (PPM_EQUAL(lastp, *pP))
  347.             run++;
  348.         else if (run < RUN_THRESH)
  349.         {
  350.             while (run > 0)
  351.             {
  352.                 *p++ = ppm_lookupcolor(cht, &lastp);
  353.                 run--;
  354.                 count++;
  355.                 if (count == MAX_COUNT)
  356.                 {
  357.                     *p++ = counttochar(MAX_COUNT);
  358.                     count -= MAX_COUNT;
  359.                 }
  360.             }
  361.             run = 1;
  362.         }
  363.         else
  364.         {
  365.             if (count > 0)
  366.                 *p++ = counttochar(count);
  367.             count = 0;
  368.             while (run > 0)
  369.             {
  370.                 rep = run > MAX_RUN ? MAX_RUN : run;
  371.                 *p++ = ppm_lookupcolor(cht, &lastp);
  372.                 *p++ = runtochar(rep);
  373.                 run -= rep;
  374.             }
  375.             run = 1;
  376.         }
  377.     }
  378.     if (run < RUN_THRESH)
  379.     {
  380.         while (run > 0)
  381.         {
  382.             *p++ = ppm_lookupcolor(cht, &lastp);
  383.             run--;
  384.             count++;
  385.             if (count == MAX_COUNT)
  386.             {
  387.                 *p++ = counttochar(MAX_COUNT);
  388.                 count -= MAX_COUNT;
  389.             }
  390.         }
  391.     }
  392.     else
  393.     {
  394.         if (count > 0)
  395.             *p++ = counttochar(count);
  396.         count = 0;
  397.         while (run > 0)
  398.         {
  399.             rep = run > MAX_RUN ? MAX_RUN : run;
  400.             *p++ = ppm_lookupcolor(cht, &lastp);
  401.             *p++ = runtochar(rep);
  402.                 run -= rep;
  403.         }
  404.         run = 1;
  405.     }
  406.     if (count > 0)
  407.         *p++ = counttochar(count);
  408.  
  409.     packcols = p - packed;        /* how many did we write? */
  410.     if (cols > 250)
  411.     {
  412.         putShort(fd, packcols);
  413.         oc = packcols + 2;
  414.     }
  415.     else
  416.     {
  417.         (void) putc(packcols, fd);
  418.         oc = packcols + 1;
  419.     }
  420.  
  421.     /* now write out the packed row */
  422.     while(p != packed)
  423.     {
  424.         --p;
  425.         (void) putc(*p, fd);
  426.     }
  427.  
  428.     return (oc);
  429. }
  430.  
  431. #else    /* RUNLENGTH */
  432.  
  433. /* real dumb putRow with no compression */
  434. static int
  435. putRow(fd, row, cols, rowpixels, packed)
  436. FILE *fd;
  437. int row, cols;
  438. pixel *rowpixels;
  439. char *packed;
  440. {
  441.     register int i, j, bc, oc;
  442.     register pixel *pP;
  443.  
  444. #if notdef
  445.     bzero(aux, cols); /* aux?? */
  446. #endif /*notdef*/
  447.     bc = cols + (cols + MAX_COUNT - 1) / MAX_COUNT;
  448.     if (bc > 250)
  449.     {
  450.         putShort(fd, bc);
  451.         oc = bc + 2;
  452.     }
  453.     else
  454.     {
  455.         (void) putc(bc, fd);
  456.         oc = bc + 1;
  457.     }
  458.     for (i = 0, pP = rowpixels; i < cols;)
  459.     {
  460.         if (cols - i > MAX_COUNT)
  461.         {
  462.             (void) putc(MAX_COUNT - 1, fd);
  463.             for (j = 0; j < MAX_COUNT; j++)
  464.             {
  465.                 (void) putc(ppm_lookupcolor(cht, pP), fd);
  466.                 pP++;
  467.             }
  468.             i += MAX_COUNT;
  469.         }
  470.         else
  471.         {
  472.             (void) putc(cols - i - 1, fd);
  473.             for (j = 0; j < cols - i; j++)
  474.             {
  475.                 (void) putc(ppm_lookupcolor(cht, pP), fd);
  476.                 pP++;
  477.             }
  478.             i = cols;
  479.         }
  480.     }
  481.     return (oc);
  482. }
  483. #endif    /* RUNLENGTH */
  484.